import socket
import time
import logging
import traceback

from apiTest.case_runnning import group_run
from apiTest.serializers import TestCaseResultModelSerializer, ApiRequestResultModelSerializer
from project.models import Project
from task.models import TaskLog
from task.serializers import TaskLogModelSerializer
from utils.ding_ding_talk_utils import autograph, SendText

logging = logging.getLogger("log")


def task_run(task_info):
    """
    任务执行核心代码
    :param task_info:
    """
    logging.info("====任务开始执行====")
    start_time = time.time()
    group_pass_total = 0
    group_failed_total = 0
    cass_skip_total = 0
    cass_pass_total = 0
    case_failed_total = 0
    case_total = 0
    test_case_group_result_dto = {}
    group_id_list = task_info["group_id_list"]
    group_total = len(group_id_list)
    task_log = {
        "task_id": task_info["id"],
        "task_name": task_info["name"],
        "project_id": task_info["project_id"],
        "group_total": group_total,
        "group_pass_total": group_pass_total,
        "group_failed_total": group_failed_total,
        "case_total": case_total,
        "case_failed_total": case_failed_total,
        "cass_pass_total": cass_pass_total,
        "cass_skip_total": cass_skip_total,
        "time_consuming": 0,
        "status": 0
    }
    task_log_serializer = TaskLogModelSerializer(data=task_log)
    if task_log_serializer.is_valid():
        task_log_model = task_log_serializer.save()
        task_log["id"] = task_log_model.id
        test_case_group_result_dto["task_log_id"] = task_log_model.id
        try:
            for group_id in group_id_list:
                test_case_group_result_dto = group_run(group_id, task_info["env_id"], task_log_model.id)
                case_failed_total += test_case_group_result_dto.test_case_group_result["test_case_failed_result"]
                cass_pass_total += test_case_group_result_dto.test_case_group_result["test_case_pass_result"]
                cass_skip_total += test_case_group_result_dto.test_case_group_result["test_case_skip_result"]
                case_total += test_case_group_result_dto.test_case_group_result["test_case_count_result"]
                test_case_result = test_case_group_result_dto.test_case_result_dto.test_case_result
                test_case_result["task_log_id"] = task_log_model.id
                test_case_result["group_id"] = group_id
                serializer = TestCaseResultModelSerializer(data=test_case_result)
                if serializer.is_valid():
                    serializer.save()
                else:
                    print(serializer.errors)
                if test_case_group_result_dto.test_case_group_result["test_case_failed_result"] > 0:
                    group_failed_total += 1
                else:
                    group_pass_total += 1
                for api_request_result in test_case_group_result_dto.test_case_result_dto.api_request_result_list:
                    api_request_result["api_test_case_id"] = test_case_result["test_case_id"]
                    api_request_result["task_log_id"] = task_log_model.id
                    api_request_result["test_case_group_id"] = group_id
                    # 将接口结果保存至表中
                    serializer = ApiRequestResultModelSerializer(data=api_request_result)
                    if serializer.is_valid():
                        serializer.save()
                    else:
                        print(serializer.errors)
            task_log["group_failed_total"] = group_failed_total
            task_log["group_pass_total"] = group_pass_total
            task_log["cass_skip_total"] = cass_skip_total
            task_log["case_failed_total"] = case_failed_total
            task_log["cass_pass_total"] = cass_pass_total
            task_log["case_total"] = case_total
            if group_failed_total == 0:
                task_log["status"] = 1
            else:
                task_log["status"] = 2
        except Exception as e:
            logging.error("测试任务执行报错：{}".format(e))
            traceback.print_exc()
            task_log["exception_log"] = e
            task_log["status"] = 3
        finally:
            # 不管结果如何都要存储消息，且发送报告
            end_time = time.time()
            milliseconds = int((end_time - start_time) * 1000)
            task_log["time_consuming"] = milliseconds
            logging.info("====任务执行结束====")
            logging.info("返回任务报告：{}".format(task_log))
            TaskLog.objects.filter(id=task_log_model.id).update(**task_log)
            project = Project.objects.get(id=task_info["project_id"])
            # 判断钉钉推送知否要执行
            if task_info["is_send_ding_ding"] and project.ding_ding_autograph and project.ding_ding_talk_url:
                webhook = autograph(project.ding_ding_talk_url, project.ding_ding_autograph)
                SendText(webhook).send_text(get_send_text(task_info, task_log))
            elif task_info["is_send_ding_ding"] and project.ding_ding_talk_url and not project.ding_ding_autograph:
                SendText(project.ding_ding_talk_url).send_text(get_send_text(task_info, task_log))
            else:
                logging.info(f"不发送钉钉消息,钉钉消息发送状态为:{task_info['is_send_ding_ding']}")


    else:
        logging.error(task_log_serializer.errors)


def get_send_text(task_info, task_log):
    """
    组装顶顶发送文档
    :param task_info:
    :param task_log:
    :return:
    """
    # 获取内部ip地址
    hostname = socket.gethostname()
    ip_address = socket.gethostbyname(hostname)
    task_log_address = "http://" + ip_address + ":8082/#/reportDetail?id=" + str(task_log["id"])
    group_total = "测试用例集共：{}".format(
        str(task_log["group_total"])) + "条，总耗时：" + str(task_log["time_consuming"]) + "毫秒\n"
    group_pass_total = "测试用例集通过：{}".format(str(task_log["group_pass_total"])) + "条\n"
    group_failed_total = "测试用例集失败：{}".format(str(task_log["group_failed_total"])) + "条\n"
    case_total = "测试用例共：{}".format(str(task_log["case_total"])) + "条\n"
    case_failed_total = "用例执行失败：{}".format(str(task_log["case_failed_total"])) + "条\n"
    cass_pass_total = "测试用例通过：{}".format(str(task_log["cass_pass_total"])) + "条\n"
    cass_skip_total = "测试用例跳过：{}".format(str(task_log["cass_skip_total"])) + "条\n"
    send_text = "亲爱的Tester：您好！以下是接口自动化任务【" + task_info[
        "name"] + "】执行情况。\n" + group_total + group_pass_total + group_failed_total + case_total + cass_pass_total + \
                case_failed_total + cass_skip_total + "详情请查看平台报告\n" + "报告地址：" + task_log_address
    # 暂时采用text格式，后期可采用markDown格式
    return send_text
